// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   PiePlotter.java

package com.java4less.rchart;

import com.java4less.rchart.gc.ChartColor;
import com.java4less.rchart.gc.ChartGraphics;
import com.java4less.rchart.gc.GraphicsProvider;
import com.java4less.rchart.gc.Polygon;
import com.java4less.rchart.gc.Rectangle;
import java.util.Vector;

// Referenced classes of package com.java4less.rchart:
//			Plotter, LineStyle, ChartLabel, PieDataSerie, 
//			FillStyle, DataSerie

public class PiePlotter extends Plotter
{

	public LineStyle labelLine;
	public double radiusModifier;
	public LineStyle border;
	public boolean drawRadius;
	public boolean effect3D;
	public String labelFormat;
	public int space;
	private Vector lblPositions;

	public PiePlotter()
	{
		labelLine = null;
		radiusModifier = 1.0D;
		border = new LineStyle(0.2F, GraphicsProvider.getColor(ChartColor.BLACK), 1);
		drawRadius = false;
		effect3D = false;
		labelFormat = "";
		space = 20;
		lblPositions = new Vector(10);
		combinable = false;
		needsAxis = 0;
	}

	private String subStr(String s, String a, String b)
	{
		int p = s.indexOf(a);
		if (p >= 0)
			s = (new StringBuilder()).append(s.substring(0, p)).append(b).append(s.substring(p + a.length(), s.length())).toString();
		return s;
	}

	private boolean inRectangle(Rectangle r, Rectangle r2)
	{
		return r.intersects(r2);
	}

	private int lenLabel(ChartGraphics g, String t)
	{
		String lines[] = splitText(t);
		int max = 0;
		for (int i = 0; i < lines.length; i++)
		{
			int laenge = g.getFontWidth(lines[i]);
			if (laenge > max)
				max = laenge;
		}

		return max;
	}

	private void drawLabel(ChartGraphics g, String t, String v, int x, int y)
	{
		if (t.indexOf("@") >= 0)
		{
			ChartLabel label = new ChartLabel(t, v, false, true);
			label.initialize(g, super.chart);
			Rectangle newR = new Rectangle(x, y, label.requiredWidth, label.requiredHeight);
			for (int i = 0; i < lblPositions.size(); i++)
			{
				Rectangle r = (Rectangle)lblPositions.elementAt(i);
				if (inRectangle(r, newR))
				{
					newR = new Rectangle(newR.x, r.y + r.h, label.requiredWidth, label.requiredHeight);
					i = 0;
				}
			}

			lblPositions.addElement(newR);
			label.paint(g, newR.x, newR.y, label.requiredWidth, label.requiredHeight);
		} else
		{
			String lines[] = splitText(t);
			int maxlen = lenLabel(g, t);
			int h = g.getFontHeight() * lines.length;
			int charH = g.getFontHeight();
			int w = maxlen;
			Rectangle newR = new Rectangle(x, y, w, h);
			for (int i = 0; i < lblPositions.size(); i++)
			{
				Rectangle r = (Rectangle)lblPositions.elementAt(i);
				if (inRectangle(r, newR))
				{
					newR = new Rectangle(newR.x, r.y + r.h, w, h);
					i = 0;
				}
			}

			lblPositions.addElement(newR);
			int pos = newR.x;
			int thislen = g.getFontWidth(lines[0]);
			pos = (pos + maxlen / 2) - thislen / 2;
			g.drawString(lines[0], pos, newR.y);
			for (int i = 1; i < lines.length; i++)
			{
				pos = newR.x;
				thislen = g.getFontWidth(lines[i]);
				pos = (pos + maxlen / 2) - thislen / 2;
				g.drawString(lines[i], pos, newR.y + charH * i);
			}

		}
	}

	private String[] splitText(String s)
	{
		String r[] = new String[100];
		int lines = 0;
		do
		{
			if (s.indexOf("\\n") <= -1)
				break;
			r[lines] = s.substring(0, s.indexOf("\\n"));
			s = s.substring(s.indexOf("\\n") + 2, s.length());
		} while (++lines < r.length);
		r[lines] = s;
		String a[] = new String[lines + 1];
		for (int i = 0; i <= lines; i++)
			a[i] = r[i];

		return a;
	}

	protected void plotSerie(ChartGraphics g, DataSerie s, int serieSec)
	{
		double lastPercent = 0.0D;
		double lastAngle = 0.0D;
		int tmpY = y;
		int border3D = 1;
		lblPositions.removeAllElements();
		s.hotAreas.removeAllElements();
		PieDataSerie p;
		if (s instanceof PieDataSerie)
			p = (PieDataSerie)s;
		else
			return;
		int count = p.yData.size();
		double ZPositionMin[] = new double[count];
		double ZPositionMax[] = new double[count];
		int ZPositionSortedMaxs[] = new int[count];
		int ZPositionSortedMins[] = new int[count];
		double lastAngles[] = new double[count];
		double angles[] = new double[count];
		double lastPercents[] = new double[count];
		double percents[] = new double[count];
		lastAngle = 0.0D;
		lastPercent = 0.0D;
		for (int i = 0; i < count; i++)
		{
			double YValue = ((Double)p.getElementY(i)).doubleValue();
			double percent = (YValue * 100D) / p.total;
			int tu;
			if (YValue == 0.0D)
				tu = 0;
			double angle = percent * 3.6000000000000001D;
			angle = (double)Math.round(lastAngle + angle) - lastAngle;
			if (i == count - 1)
				angle = 360D - lastAngle;
			percents[i] = percent;
			angles[i] = angle;
			lastPercents[i] = lastPercent;
			lastAngles[i] = lastAngle;
			double radian = 0.017452777777777779D * lastAngle;
			double Sin = Math.sin(radian);
			ZPositionMin[i] = Sin * 1.0D;
			ZPositionMax[i] = Sin * 1.0D;
			radian = 0.017452777777777779D * (lastAngle + angle);
			Sin = Math.sin(radian);
			double tmp = Sin * 1.0D;
			if (tmp > ZPositionMax[i])
				ZPositionMax[i] = tmp;
			if (tmp < ZPositionMin[i])
				ZPositionMin[i] = tmp;
			if (lastAngle <= 270D && angle >= 270D)
				ZPositionMin[i] = -1D;
			if (lastAngle <= 90D && angle >= 90D)
				ZPositionMax[i] = 1.0D;
			lastAngle += angle;
			lastPercent += percent;
			Polygon po = new Polygon();
			s.hotAreas.addElement(po);
		}

		for (int i = 0; i < count; i++)
		{
			double maxZ = -2D;
			int maxZIndex = 0;
			double maxminZ = -2D;
			int maxminZIndex = 0;
			for (int k = 0; k < count; k++)
			{
				if (ZPositionMax[k] > maxZ)
				{
					maxZ = ZPositionMax[k];
					maxZIndex = k;
				}
				if (ZPositionMin[k] > maxminZ)
				{
					maxminZ = ZPositionMin[k];
					maxminZIndex = k;
				}
			}

			ZPositionSortedMaxs[i] = maxZIndex;
			ZPositionSortedMins[i] = maxminZIndex;
			ZPositionMin[maxminZIndex] = -2D;
			ZPositionMax[maxZIndex] = -2D;
		}

		int radi = 0;
		int radiy = 0;
		radi = width;
		if (height < radi)
			radi = height;
		radi = (int)((double)radi * radiusModifier);
		int toCenterX = (width - radi) / 2;
		int toCenterY = (height - radi) / 2;
		radiy = radi;
		if (effect3D)
		{
			radiy = (int)((double)radi * 0.5D);
			border3D = (int)((double)radi * 0.14999999999999999D);
			tmpY += radiy / 2;
		}
		int PieCenterX = toCenterX + x + radi / 2;
		int PieCenterY = toCenterY + tmpY + radi / 2;
		for (int j = 0; j < 3; j++)
		{
			for (int h = border3D - 1; h >= 0 && (j != 2 || h == border3D - 1); h--)
			{
				for (int l = 0; l < count; l++)
				{
					int i;
					if (j == 0)
						i = ZPositionSortedMaxs[l];
					else
						i = ZPositionSortedMins[l];
					boolean keepTogether = true;
					if (p.itemsTogether.size() >= i)
						keepTogether = ((Boolean)p.itemsTogether.elementAt(i)).booleanValue();
					if (!keepTogether)
						border = null;
					int movedX = 0;
					int movedY = 0;
					double YValue = ((Double)p.getElementY(i)).doubleValue();
					FillStyle currentStyle = (FillStyle)(FillStyle)p.Styles.elementAt(i);
					if (currentStyle == null)
						currentStyle = new FillStyle(GraphicsProvider.getColor(ChartColor.WHITE));
					LineStyle darkerLine = new LineStyle(0.2F, currentStyle.color.darker(), 1);
					if (h > 2)
						currentStyle = new FillStyle(currentStyle.color.darker().darker());
					if (!keepTogether)
					{
						double tmpAngle = lastAngles[i] + angles[i] / 2D;
						double radian = 0.017452777777777779D * tmpAngle;
						double Sin = Math.sin(radian);
						double Cos = Math.cos(radian);
						movedY = (int)(Sin * (double)space);
						movedX = (int)(Cos * (double)space);
						movedY *= -1;
						movedX *= -1;
						if (effect3D)
							movedY /= 2;
					}
					if (j == 0 || j == 1)
					{
						boolean drawNow = false;
						double tmplastAngle = lastAngles[i];
						double tmpangle = angles[i];
						if (j == 0 && lastAngles[i] + angles[i] <= 180D)
							drawNow = true;
						if (j == 1 && lastAngles[i] >= 180D && lastAngles[i] + angles[i] >= 180D)
							drawNow = true;
						if (j == 1 && lastAngles[i] <= 180D && lastAngles[i] + angles[i] >= 180D)
						{
							drawNow = true;
							tmpangle = (tmpangle + tmplastAngle) - 180D;
							tmplastAngle = 180D;
						}
						if (j == 0 && lastAngles[i] < 180D && lastAngles[i] + angles[i] > 180D)
						{
							drawNow = true;
							tmpangle = 180D - tmplastAngle;
						}
						if (drawNow)
						{
							currentStyle.drawArc(g, toCenterX + x + movedX, toCenterY + movedY + tmpY + h, radi, radiy, (int)tmplastAngle, (int)tmpangle);
							if (h > 0)
								darkerLine.drawArc(g, toCenterX + x + movedX, toCenterY + movedY + tmpY + h, radi, radiy, (int)tmplastAngle, (int)tmpangle);
						}
					}
					if (border != null && j == 2)
					{
						border.drawArc(g, toCenterX + x, toCenterY + tmpY, radi, radiy, (int)lastAngles[i], (int)angles[i]);
						if (effect3D)
						{
							border.drawArc(g, toCenterX + x, toCenterY + tmpY + (border3D - 1), radi, radiy, 180, 180);
							border.draw(g, toCenterX + x, toCenterY + tmpY + radiy / 2, toCenterX + x, toCenterY + tmpY + radiy / 2 + border3D);
							border.draw(g, toCenterX + x + radi, toCenterY + tmpY + radiy / 2, toCenterX + x + radi, toCenterY + tmpY + radiy / 2 + border3D);
						}
						double radian = 0.017452777777777779D * (lastAngles[i] + angles[i]);
						double Sin = Math.sin(radian);
						double Cos = Math.cos(radian);
						int relativeY = (int)(Sin * (double)(radi / 2));
						int relativeX = (int)(Cos * (double)(radi / 2));
						relativeY *= -1;
						if (drawRadius && !effect3D)
							border.draw(g, PieCenterX, PieCenterY, PieCenterX + relativeX, PieCenterY + relativeY);
					}
					if (j == 2)
					{
						h = border3D - 1;
						Polygon po = (Polygon)s.hotAreas.elementAt(i);
						po.addPoint(PieCenterX + movedX, toCenterY + tmpY + radiy / 2 + movedY);
						int xModifier = 1;
						int yModifier = -1;
						double normAngle = lastAngles[i] + angles[i];
						double radian = 0.017452777777777779D * normAngle;
						double Sin = Math.sin(radian);
						double Cos = Math.cos(radian);
						int relativeY = (int)(Sin * (double)(radiy / 2));
						int relativeX = (int)(Cos * (double)(radi / 2));
						relativeX *= xModifier;
						relativeY *= yModifier;
						po.addPoint(PieCenterX + relativeX + movedX, toCenterY + tmpY + radiy / 2 + relativeY + movedY);
						xModifier = 1;
						yModifier = -1;
						normAngle = lastAngles[i] + (angles[i] * 2D) / 3D;
						radian = 0.017452777777777779D * normAngle;
						Sin = Math.sin(radian);
						Cos = Math.cos(radian);
						relativeY = (int)(Sin * (double)(radiy / 2));
						relativeX = (int)(Cos * (double)(radi / 2));
						relativeX *= xModifier;
						relativeY *= yModifier;
						po.addPoint(PieCenterX + relativeX + movedX, toCenterY + tmpY + radiy / 2 + relativeY + movedY);
						xModifier = 1;
						yModifier = -1;
						normAngle = lastAngles[i] + angles[i] / 3D;
						radian = 0.017452777777777779D * normAngle;
						Sin = Math.sin(radian);
						Cos = Math.cos(radian);
						relativeY = (int)(Sin * (double)(radiy / 2));
						relativeX = (int)(Cos * (double)(radi / 2));
						relativeX *= xModifier;
						relativeY *= yModifier;
						po.addPoint(PieCenterX + relativeX + movedX, toCenterY + tmpY + radiy / 2 + relativeY + movedY);
						xModifier = 1;
						yModifier = -1;
						normAngle = lastAngles[i];
						radian = 0.017452777777777779D * normAngle;
						Sin = Math.sin(radian);
						Cos = Math.cos(radian);
						relativeY = (int)(Sin * (double)(radiy / 2));
						relativeX = (int)(Cos * (double)(radi / 2));
						relativeX *= xModifier;
						relativeY *= yModifier;
						po.addPoint(PieCenterX + relativeX + movedX, toCenterY + tmpY + radiy / 2 + relativeY + movedY);
					}
					if (p.valueFont == null || j != 2)
						continue;
					g.setColor(p.valueColor);
					g.setFont(p.valueFont);
					String txt = p.doubleToString(new Double(percents[i]));
					if (txt.compareTo("") == 0)
						txt = "0";
					txt = (new StringBuilder()).append(txt).append(" %").toString();
					String percenStr = txt;
					String absoluteStr = p.doubleToString(new Double(YValue));
					if (absoluteStr.compareTo("") == 0)
						absoluteStr = "0";
					if (!p.drawPercentages)
						txt = absoluteStr;
					if (labelFormat.length() > 0)
					{
						txt = labelFormat;
						txt = subStr(txt, "#PERCENTAGE#", percenStr);
						txt = subStr(txt, "#VALUE#", absoluteStr);
						if (p.itemsLabel.size() > i)
							txt = subStr(txt, "#LABEL#", (String)p.itemsLabel.elementAt(i));
					}
					String txtValue = txt;
					if (p.labelTemplate.length() > 0)
						txt = p.labelTemplate;
					if (p.dataLabels != null && p.dataLabels.length > i)
						txt = p.dataLabels[i];
					int xModifier = 1;
					int yModifier = -1;
					double normAngle = lastAngles[i] + angles[i] / 2D;
					int relativeX = 0;
					int relativeY = 0;
					double radian = 0.017452777777777779D * normAngle;
					double Sin = Math.sin(radian);
					double Cos = Math.cos(radian);
					relativeY = (int)(Sin * (double)(radiy / 2) * p.textDistanceToCenter);
					relativeX = (int)(Cos * (double)(radi / 2) * p.textDistanceToCenter);
					relativeX = relativeX * xModifier * -1;
					relativeY *= yModifier;
					int toCenterValueX = 5;
					if (Cos < 0.0D)
						toCenterValueX = (lenLabel(g, txt) + 5) * -1;
					int toCenterValueY = g.getFontHeight() + 5;
					if (Sin > 0.0D)
						toCenterValueY = -5;
					int labelx = 0;
					int labely = 0;
					if (effect3D)
					{
						labelx = PieCenterX + movedX + relativeX + toCenterValueX;
						labely = toCenterY + tmpY + radiy / 2 + movedY + relativeY + toCenterValueY;
					} else
					{
						labelx = PieCenterX + relativeX + toCenterValueX;
						labely = PieCenterY + relativeY + toCenterValueY;
					}
					int borderMiddleX = 0;
					int borderMiddleY = 0;
					double middlePointAngle = lastAngles[i] + angles[i] / 2D;
					xModifier = 1;
					yModifier = -1;
					normAngle = middlePointAngle;
					radian = 0.017452777777777779D * normAngle;
					Sin = Math.sin(radian);
					Cos = Math.cos(radian);
					relativeY = (int)(Sin * (double)(radiy / 2));
					relativeX = (int)(Cos * (double)(radi / 2));
					relativeX = relativeX * xModifier * -1;
					relativeY *= yModifier;
					borderMiddleX = PieCenterX + relativeX + movedX;
					borderMiddleY = toCenterY + tmpY + radiy / 2 + relativeY + movedY;
					if (labelLine != null)
					{
						int endLineX = labelx;
						int endLineY = labely;
						int endLineX2 = labelx;
						int endLineY2 = labely;
						int txtLength = g.getFontWidth(txt);
						int txtHeight = g.getFontHeight();
						if (middlePointAngle <= 45D || middlePointAngle >= 315D)
						{
							endLineX = labelx - 10;
							endLineY = labely;
							endLineX2 = labelx - 1;
							endLineY2 = labely;
						}
						if (middlePointAngle >= 45D && middlePointAngle <= 135D)
						{
							endLineX = labelx + txtLength / 2;
							endLineY = labely + 10;
							endLineX2 = labelx + txtLength / 2;
							endLineY2 = labely + 2;
						}
						if (middlePointAngle <= 225D && middlePointAngle >= 135D)
						{
							endLineX = labelx + txtLength + 10;
							endLineY = labely;
							endLineX2 = labelx + txtLength;
							endLineY2 = labely;
						}
						if (middlePointAngle >= 225D && middlePointAngle <= 315D)
						{
							endLineX = labelx + txtLength / 2;
							endLineY = labely - txtHeight - 10;
							endLineX2 = labelx + txtLength / 2;
							endLineY2 = labely - txtHeight - 2;
						}
						labelLine.draw(g, endLineX, endLineY, borderMiddleX, borderMiddleY);
						labelLine.draw(g, endLineX, endLineY, endLineX2, endLineY2);
					}
					drawLabel(g, txt, txtValue, labelx, labely);
				}

			}

		}

	}
}
